<?php defined('SYSPATH') or die('No direct script access.');

/**
 * @example 三种情况
 *
 */
class Model_Publish extends Model {

	private $_config;

	public function __construct()
	{
		parent::__construct();
		
		$this->_config = Kohana::$config->load('publish');


		foreach ($this->_config['warning_files'] as $key => $value) {
			$this->_config['warn_files'][$key] = str_replace(array('/','\\',DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR), DIRECTORY_SEPARATOR, $value);
		}

	}

	public function is_warning($path)
	{
		foreach($this->_config['warning_files'] as $value)
		{
			if (pcre_fnmatch($value, $path, FNM_CASEFOLD | FNM_NOESCAPE))
				return TRUE;
		}
		return FALSE;
	}


	public function get_file_list() 
	{
		$result = array();
		foreach (array('APPPATH','MODPATH','SYSPATH') as $path) {
			$list = file_list(constant($path), $this->_config['ignore_files'], TRUE);
			$list = array_add_selector($list, array('hash' => '', 'warning' => FALSE), '*'); //添加一个hash到每个数组子项
			$_list = $this->get_cache($path, array()); //读取缓存
			foreach ($list as $key => $value) {
				array_key_exists($key, $_list) && $value['type'] == 'file' && $list[$key]['hash'] = $_list[$key]['hash']; //如果是文件，将历史hash赋值给新数据
				if (!array_key_exists($key, $_list) || $_list[$key]['type'] != $value['type']  || $_list[$key]['size'] != $value['size'] || $_list[$key]['mtime'] != $value['mtime'] || empty($_list[$key]['hash'])) //如果文件被修改，则重新读取md5
					$value['type'] == 'file' && $list[$key]['hash'] = md5_file($value['path']);
					$list[$key]['warning'] = $this->is_warning($value['path']);
			}
			$this->set_cache($path, $list, Date::YEAR); //将更新后的数组存入缓存
			
			$result[$path] = $list;
			unset($list, $_list);
		}
		return $result;
	}

	public function get_file_content($path)
	{
		$path = str_replace(array('APPPATH','MODPATH','SYSPATH'), array(APPPATH,MODPATH,SYSPATH), $path);
		return file_exists($path) ? file_get_contents($path) : FALSE;
	}


	public function compare_file_list(&$local, &$remote)
	{
		$callback = create_function('$a,$b', "return strcasecmp(\$a['hash'], \$b['hash']);");
		$diff = array();
		foreach (array('APPPATH','MODPATH','SYSPATH') as $path) {
			$data = array_udiff_assoc($local[$path], $remote[$path], $callback) + array_udiff_assoc($remote[$path], $local[$path], $callback);
			foreach($data as $key => $v)
			{
				$diff[$path][$key] = array(
					'local' => $local[$path][$key],
					'remote' => $remote[$path][$key],
					'path' => Encrypt::instance()->encode($key),
				);
			}
			!empty($diff[$path]) && ksort($diff[$path]);
		}
		return $diff;
	}

	public function file_type($file)
	{
		$ext = strtolower(fileext($file));
		foreach ($this->_config['file_type'] as $key => $value) {
			if (in_array($ext, $value))
				return $key;
		}
	}
}